import chisel3._
import chisel3.util._

object InstructionList {
  // Arithmetic Operation
  val ADD     = BitPat("b000000 ????? ????? ????? 00000 100000")
  val ADDI    = BitPat("b001000 ????? ????? ????? ????? ??????")
  val ADDU    = BitPat("b000000 ????? ????? ????? 00000 100001")
  val ADDIU   = BitPat("b001001 ????? ????? ????? ????? ??????")
  val SUB     = BitPat("b000000 ????? ????? ????? 00000 100010")
  val SUBU    = BitPat("b000000 ????? ????? ????? 00000 100011")
  val SLT     = BitPat("b000000 ????? ????? ????? 00000 101010")
  val SLTI    = BitPat("b001010 ????? ????? ????? ????? ??????")
  val SLTU    = BitPat("b000000 ????? ????? ????? 00000 101011")
  val SLTIU   = BitPat("b001011 ????? ????? ????? ????? ??????")
  val DIV     = BitPat("b000000 ????? ????? 00000 00000 011010")
  val DIVU    = BitPat("b000000 ????? ????? 00000 00000 011011")
  val MULT    = BitPat("b000000 ????? ????? 00000 00000 011000")
  val MULTU   = BitPat("b000000 ????? ????? 00000 00000 011001")
  // Logical Operation
  val AND     = BitPat("b000000 ????? ????? ????? 00000 100100")
  val ANDI    = BitPat("b001100 ????? ????? ????? ????? ??????")
  val LUI     = BitPat("b001111 ????? ????? ????? ????? ??????")
  val NOR     = BitPat("b000000 ????? ????? ????? 00000 100111")
  val OR      = BitPat("b000000 ????? ????? ????? 00000 100101")
  val ORI     = BitPat("b001101 ????? ????? ????? ????? ??????")
  val XOR     = BitPat("b000000 ????? ????? ????? 00000 100110")
  val XORI    = BitPat("b001110 ????? ????? ????? ????? ??????")
  // Shift Operation
  val SLLV    = BitPat("b000000 ????? ????? ????? 00000 000100")
  val SLL     = BitPat("b000000 00000 ????? ????? ????? 000000")
  val SRAV    = BitPat("b000000 ????? ????? ????? 00000 000111")
  val SRA     = BitPat("b000000 00000 ????? ????? ????? 000011")
  val SRLV    = BitPat("b000000 ????? ????? ????? 00000 000110")
  val SRL     = BitPat("b000000 00000 ????? ????? ????? 000010")
  // Branch & Jump
  val BEQ     = BitPat("b000100 ????? ????? ????? ????? ??????")
  val BNE     = BitPat("b000101 ????? ????? ????? ????? ??????")
  val BGEZ    = BitPat("b000001 ????? 00001 ????? ????? ??????")
  val BGTZ    = BitPat("b000111 ????? 00000 ????? ????? ??????")
  val BLEZ    = BitPat("b000110 ????? 00000 ????? ????? ??????")
  val BLTZ    = BitPat("b000001 ????? 00000 ????? ????? ??????")
  val BGEZAL  = BitPat("b000001 ????? 10001 ????? ????? ??????")
  val BLTZAL  = BitPat("b000001 ????? 10000 ????? ????? ??????")
  val J       = BitPat("b000010 ????? ????? ????? ????? ??????")
  val JAL     = BitPat("b000011 ????? ????? ????? ????? ??????")
  val JR      = BitPat("b000000 ????? 00000 00000 00000 001000")
  val JALR    = BitPat("b000000 ????? 00000 ????? 00000 001001")
  // Data Transfer
  val MFHI    = BitPat("b000000 00000 00000 ????? 00000 010000")
  val MFLO    = BitPat("b000000 00000 00000 ????? 00000 010010")
  val MTHI    = BitPat("b000000 ????? 00000 00000 00000 010001")
  val MTLO    = BitPat("b000000 ????? 00000 00000 00000 010011")
  // Trap
  val BREAK   = BitPat("b000000 ????? ????? ????? ????? 001101")
  val SYSCALL = BitPat("b000000 ????? ????? ????? ????? 001100")
  // Memory Access
  val LB      = BitPat("b100000 ????? ????? ????? ????? ??????")
  val LBU     = BitPat("b100100 ????? ????? ????? ????? ??????")
  val LH      = BitPat("b100001 ????? ????? ????? ????? ??????")
  val LHU     = BitPat("b100101 ????? ????? ????? ????? ??????")
  val LW      = BitPat("b100011 ????? ????? ????? ????? ??????")
  val SB      = BitPat("b101000 ????? ????? ????? ????? ??????")
  val SH      = BitPat("b101001 ????? ????? ????? ????? ??????")
  val SW      = BitPat("b101011 ????? ????? ????? ????? ??????")
  // Privileged
  val ERET    = BitPat("b010000 10000 00000 00000 00000 011000")
  val MFC0    = BitPat("b010000 00000 ????? ????? 00000 000???")
  val MTC0    = BitPat("b010000 00100 ????? ????? 00000 000???")
}

object ALUOperationList {
  val alu_adds  = 0.U
  val alu_addu  = 1.U
  val alu_subs  = 2.U
  val alu_subu  = 3.U
  val alu_mults = 4.U
  val alu_multu = 5.U
  val alu_divs  = 6.U
  val alu_divu  = 7.U
  val alu_and   = 8.U
  val alu_xor   = 9.U
  val alu_nor   = 10.U
  val alu_or    = 11.U
  val alu_sftrs = 12.U
  val alu_sftru = 13.U
  val alu_sftl  = 14.U
  val alu_nop   = 15.U
}

object CP0RegisterList {
  val badvaddr = 8.U
  val count    = 9.U
  val status   = 12.U
  val cause    = 13.U
  val epc      = 14.U
}